/*
 * SpringBoot WebMVC基础示例 - Java Web框架详解
 * 
 * 本文件展示SpringBoot WebMVC的基本用法，包括控制器定义、请求处理、响应格式等核心功能。
 * 对比FastAPI，帮助Python工程师理解Java Web开发的特点。
 * 
 * 与FastAPI对比：
 * 1. SpringBoot使用注解定义路由，FastAPI使用装饰器
 * 2. SpringBoot需要额外配置生成API文档，FastAPI自动生成
 * 3. SpringBoot使用Bean Validation验证，FastAPI内置Pydantic验证
 * 4. SpringBoot异步需要WebFlux，FastAPI原生支持async/await
 * 
 * 作者: Assistant
 * 日期: 2024
 */

package com.example.demo;

// ============================================================================
// 1. 依赖导入
// ============================================================================

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import javax.validation.Valid;
import javax.validation.constraints.*;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

// ============================================================================
// 2. 数据模型定义 (相当于Python的Pydantic模型)
// ============================================================================

/**
 * 用户状态枚举
 * 相当于Python的UserStatus(str, Enum)
 */
enum UserStatus {
    ACTIVE("active"),
    INACTIVE("inactive"),
    SUSPENDED("suspended");
    
    private final String value;
    
    UserStatus(String value) {
        this.value = value;
    }
    
    public String getValue() {
        return value;
    }
}

/**
 * 创建用户请求模型
 * 相当于Python的UserCreateRequest
 * 
 * Java特点：
 * 1. 使用Bean Validation注解验证
 * 2. Lombok自动生成getter/setter
 * 3. 需要显式定义所有约束
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
class UserCreateRequest {
    
    @NotBlank(message = "用户姓名不能为空")
    @Size(min = 2, max = 50, message = "用户姓名长度必须在2-50之间")
    @Pattern(regexp = "^[^0-9]*$", message = "姓名不能包含数字")
    private String name;
    
    @NotBlank(message = "邮箱地址不能为空")
    @Email(message = "邮箱格式不正确")
    @Pattern(regexp = "^[\\w\\.-]+@[\\w\\.-]+\\.\\w+$", message = "邮箱格式不正确")
    private String email;
    
    @NotNull(message = "年龄不能为空")
    @Min(value = 18, message = "年龄不能小于18岁")
    @Max(value = 120, message = "年龄不能大于120岁")
    private Integer age;
    
    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号码格式不正确")
    private String phone;
    
    @Size(max = 5, message = "标签数量不能超过5个")
    private List<String> tags = new ArrayList<>();
    
    // 自定义验证方法（需要配合自定义验证器）
    public void validateTags() {
        if (tags != null) {
            tags = tags.stream()
                .filter(Objects::nonNull)
                .map(String::trim)
                .map(String::toLowerCase)
                .filter(tag -> !tag.isEmpty())
                .collect(Collectors.toList());
        }
    }
}

/**
 * 用户响应模型
 * 相当于Python的UserResponse
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
class UserResponse {
    
    private Long id;
    
    private String name;
    
    private String email;
    
    private Integer age;
    
    private String phone;
    
    private UserStatus status;
    
    private List<String> tags = new ArrayList<>();
    
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
    private LocalDateTime createdAt;
    
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
    private LocalDateTime updatedAt;
}

/**
 * 更新用户请求模型
 * 所有字段都是可选的，支持部分更新
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
class UserUpdateRequest {
    
    @Size(min = 2, max = 50, message = "用户姓名长度必须在2-50之间")
    @Pattern(regexp = "^[^0-9]*$", message = "姓名不能包含数字")
    private String name;
    
    @Email(message = "邮箱格式不正确")
    private String email;
    
    @Min(value = 18, message = "年龄不能小于18岁")
    @Max(value = 120, message = "年龄不能大于120岁")
    private Integer age;
    
    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号码格式不正确")
    private String phone;
    
    private UserStatus status;
    
    @Size(max = 5, message = "标签数量不能超过5个")
    private List<String> tags;
}

/**
 * 统一API响应格式
 * 相当于Python的ApiResponse
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
class ApiResponse<T> {
    
    private boolean success;
    
    private String message;
    
    private T data;
    
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
    private LocalDateTime timestamp = LocalDateTime.now();
    
    // 静态工厂方法
    public static <T> ApiResponse<T> success(String message, T data) {
        return ApiResponse.<T>builder()
            .success(true)
            .message(message)
            .data(data)
            .timestamp(LocalDateTime.now())
            .build();
    }
    
    public static <T> ApiResponse<T> error(String message) {
        return ApiResponse.<T>builder()
            .success(false)
            .message(message)
            .data(null)
            .timestamp(LocalDateTime.now())
            .build();
    }
}

/**
 * 分页响应模型
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
class PaginationResponse<T> {
    
    private List<T> items;
    
    private long total;
    
    private int page;
    
    private int size;
    
    private int pages;
    
    // 计算总页数
    public static <T> PaginationResponse<T> of(List<T> items, long total, int page, int size) {
        int pages = (int) Math.ceil((double) total / size);
        return PaginationResponse.<T>builder()
            .items(items)
            .total(total)
            .page(page)
            .size(size)
            .pages(pages)
            .build();
    }
}

// ============================================================================
// 3. 数据存储服务 (相当于Python的UserStorage)
// ============================================================================

/**
 * 用户数据存储服务
 * 模拟数据库操作，实际项目中会使用JPA Repository
 * 相当于Python的UserStorage类
 */
@Service
class UserStorageService {
    
    private final Map<Long, UserResponse> users = new ConcurrentHashMap<>();
    private final AtomicLong nextId = new AtomicLong(1);
    
    // 构造函数中初始化测试数据
    public UserStorageService() {
        initTestData();
    }
    
    /**
     * 初始化测试数据
     */
    private void initTestData() {
        List<UserCreateRequest> testUsers = Arrays.asList(
            UserCreateRequest.builder()
                .name("张三")
                .email("zhangsan@example.com")
                .age(25)
                .phone("13800138000")
                .tags(Arrays.asList("developer", "java"))
                .build(),
            UserCreateRequest.builder()
                .name("李四")
                .email("lisi@example.com")
                .age(30)
                .phone("13900139000")
                .tags(Arrays.asList("manager", "python"))
                .build(),
            UserCreateRequest.builder()
                .name("王五")
                .email("wangwu@example.com")
                .age(28)
                .tags(Arrays.asList("designer", "ui"))
                .build()
        );
        
        for (UserCreateRequest userData : testUsers) {
            createUser(userData);
        }
    }
    
    /**
     * 创建用户
     */
    public UserResponse createUser(UserCreateRequest userData) {
        // 检查邮箱是否已存在
        boolean emailExists = users.values().stream()
            .anyMatch(user -> user.getEmail().equals(userData.getEmail()));
        
        if (emailExists) {
            throw new IllegalArgumentException("邮箱 " + userData.getEmail() + " 已存在");
        }
        
        userData.validateTags();
        
        Long userId = nextId.getAndIncrement();
        LocalDateTime now = LocalDateTime.now();
        
        UserResponse user = UserResponse.builder()
            .id(userId)
            .name(userData.getName())
            .email(userData.getEmail())
            .age(userData.getAge())
            .phone(userData.getPhone())
            .status(UserStatus.ACTIVE)
            .tags(userData.getTags())
            .createdAt(now)
            .updatedAt(now)
            .build();
        
        users.put(userId, user);
        return user;
    }
    
    /**
     * 获取用户
     */
    public Optional<UserResponse> getUser(Long userId) {
        return Optional.ofNullable(users.get(userId));
    }
    
    /**
     * 获取用户列表
     */
    public List<UserResponse> getUsers(int skip, int limit, UserStatus status, String tag) {
        return users.values().stream()
            .filter(user -> status == null || user.getStatus() == status)
            .filter(user -> tag == null || user.getTags().stream()
                .anyMatch(t -> t.toLowerCase().contains(tag.toLowerCase())))
            .sorted((u1, u2) -> u2.getCreatedAt().compareTo(u1.getCreatedAt()))
            .skip(skip)
            .limit(limit)
            .collect(Collectors.toList());
    }
    
    /**
     * 获取用户总数
     */
    public long getUserCount(UserStatus status, String tag) {
        return users.values().stream()
            .filter(user -> status == null || user.getStatus() == status)
            .filter(user -> tag == null || user.getTags().stream()
                .anyMatch(t -> t.toLowerCase().contains(tag.toLowerCase())))
            .count();
    }
    
    /**
     * 更新用户
     */
    public Optional<UserResponse> updateUser(Long userId, UserUpdateRequest userData) {
        UserResponse existingUser = users.get(userId);
        if (existingUser == null) {
            return Optional.empty();
        }
        
        // 检查邮箱唯一性
        if (userData.getEmail() != null && !userData.getEmail().equals(existingUser.getEmail())) {
            boolean emailExists = users.values().stream()
                .anyMatch(user -> !user.getId().equals(userId) && 
                         user.getEmail().equals(userData.getEmail()));
            
            if (emailExists) {
                throw new IllegalArgumentException("邮箱 " + userData.getEmail() + " 已存在");
            }
        }
        
        // 更新字段
        UserResponse.UserResponseBuilder builder = existingUser.toBuilder();
        
        if (userData.getName() != null) {
            builder.name(userData.getName());
        }
        if (userData.getEmail() != null) {
            builder.email(userData.getEmail());
        }
        if (userData.getAge() != null) {
            builder.age(userData.getAge());
        }
        if (userData.getPhone() != null) {
            builder.phone(userData.getPhone());
        }
        if (userData.getStatus() != null) {
            builder.status(userData.getStatus());
        }
        if (userData.getTags() != null) {
            builder.tags(userData.getTags());
        }
        
        builder.updatedAt(LocalDateTime.now());
        
        UserResponse updatedUser = builder.build();
        users.put(userId, updatedUser);
        
        return Optional.of(updatedUser);
    }
    
    /**
     * 删除用户
     */
    public boolean deleteUser(Long userId) {
        return users.remove(userId) != null;
    }
    
    /**
     * 搜索用户
     */
    public List<UserResponse> searchUsers(String keyword) {
        String lowerKeyword = keyword.toLowerCase();
        
        return users.values().stream()
            .filter(user -> 
                user.getName().toLowerCase().contains(lowerKeyword) ||
                user.getEmail().toLowerCase().contains(lowerKeyword) ||
                user.getTags().stream().anyMatch(tag -> 
                    tag.toLowerCase().contains(lowerKeyword))
            )
            .collect(Collectors.toList());
    }
    
    /**
     * 获取所有用户（用于统计）
     */
    public List<UserResponse> getAllUsers() {
        return new ArrayList<>(users.values());
    }
}

// ============================================================================
// 4. 控制器定义 (相当于Python的FastAPI路由)
// ============================================================================

/**
 * 用户管理控制器
 * 相当于Python的FastAPI app路由定义
 * 
 * SpringBoot特点：
 * 1. 使用@RestController注解
 * 2. 使用@RequestMapping定义基础路径
 * 3. 使用@Autowired注入依赖
 * 4. 使用@Valid验证请求体
 */
@RestController
@RequestMapping("/api")
@Validated
class UserController {
    
    @Autowired
    private UserStorageService userStorage;
    
    /**
     * 首页
     * 相当于Python的@app.get("/")
     */
    @GetMapping("/")
    public ResponseEntity<String> root() {
        String html = """
            <html>
                <head>
                    <title>SpringBoot用户管理系统</title>
                </head>
                <body>
                    <h1>欢迎使用SpringBoot用户管理系统</h1>
                    <p>这是一个演示SpringBoot WebMVC基础功能的示例应用</p>
                    <ul>
                        <li><a href="/swagger-ui.html">API文档 (Swagger UI)</a></li>
                        <li><a href="/api/health">健康检查</a></li>
                    </ul>
                </body>
            </html>
            """;
        
        return ResponseEntity.ok()
            .header("Content-Type", "text/html; charset=utf-8")
            .body(html);
    }
    
    /**
     * 健康检查接口
     * 相当于Python的@app.get("/health")
     */
    @GetMapping("/health")
    public ResponseEntity<ApiResponse<Map<String, Object>>> healthCheck() {
        Map<String, Object> healthData = new HashMap<>();
        healthData.put("status", "healthy");
        healthData.put("timestamp", LocalDateTime.now());
        healthData.put("version", "1.0.0");
        
        return ResponseEntity.ok(
            ApiResponse.success("服务运行正常", healthData)
        );
    }
    
    /**
     * 创建用户
     * 相当于Python的@app.post("/users")
     */
    @PostMapping("/users")
    public ResponseEntity<ApiResponse<UserResponse>> createUser(
            @Valid @RequestBody UserCreateRequest userData) {
        
        try {
            UserResponse user = userStorage.createUser(userData);
            System.out.println("创建用户成功: " + user.getName() + " (" + user.getEmail() + ")");
            
            return ResponseEntity.status(HttpStatus.CREATED)
                .body(ApiResponse.success("用户创建成功", user));
                
        } catch (IllegalArgumentException e) {
            System.out.println("创建用户失败: " + e.getMessage());
            return ResponseEntity.badRequest()
                .body(ApiResponse.error(e.getMessage()));
        }
    }
    
    /**
     * 获取用户详情
     * 相当于Python的@app.get("/users/{user_id}")
     */
    @GetMapping("/users/{userId}")
    public ResponseEntity<ApiResponse<UserResponse>> getUser(
            @PathVariable @Min(1) Long userId) {
        
        Optional<UserResponse> user = userStorage.getUser(userId);
        
        if (user.isEmpty()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                .body(ApiResponse.error("用户 " + userId + " 不存在"));
        }
        
        System.out.println("获取用户详情: " + user.get().getName());
        return ResponseEntity.ok(
            ApiResponse.success("获取用户成功", user.get())
        );
    }
    
    /**
     * 获取用户列表（分页）
     * 相当于Python的@app.get("/users")
     */
    @GetMapping("/users")
    public ResponseEntity<ApiResponse<PaginationResponse<UserResponse>>> getUsers(
            @RequestParam(defaultValue = "1") @Min(1) int page,
            @RequestParam(defaultValue = "10") @Min(1) @Max(100) int size,
            @RequestParam(required = false) UserStatus status,
            @RequestParam(required = false) String tag) {
        
        int skip = (page - 1) * size;
        
        List<UserResponse> users = userStorage.getUsers(skip, size, status, tag);
        long total = userStorage.getUserCount(status, tag);
        
        PaginationResponse<UserResponse> pagination = 
            PaginationResponse.of(users, total, page, size);
        
        System.out.println("获取用户列表: 页码=" + page + ", 大小=" + size + ", 总数=" + total);
        return ResponseEntity.ok(
            ApiResponse.success("获取用户列表成功", pagination)
        );
    }
    
    /**
     * 更新用户信息
     * 相当于Python的@app.put("/users/{user_id}")
     */
    @PutMapping("/users/{userId}")
    public ResponseEntity<ApiResponse<UserResponse>> updateUser(
            @PathVariable @Min(1) Long userId,
            @Valid @RequestBody UserUpdateRequest userData) {
        
        try {
            Optional<UserResponse> user = userStorage.updateUser(userId, userData);
            
            if (user.isEmpty()) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(ApiResponse.error("用户 " + userId + " 不存在"));
            }
            
            System.out.println("更新用户成功: " + user.get().getName());
            return ResponseEntity.ok(
                ApiResponse.success("用户更新成功", user.get())
            );
            
        } catch (IllegalArgumentException e) {
            System.out.println("更新用户失败: " + e.getMessage());
            return ResponseEntity.badRequest()
                .body(ApiResponse.error(e.getMessage()));
        }
    }
    
    /**
     * 删除用户
     * 相当于Python的@app.delete("/users/{user_id}")
     */
    @DeleteMapping("/users/{userId}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> deleteUser(
            @PathVariable @Min(1) Long userId) {
        
        boolean success = userStorage.deleteUser(userId);
        
        if (!success) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                .body(ApiResponse.error("用户 " + userId + " 不存在"));
        }
        
        Map<String, Object> result = new HashMap<>();
        result.put("deleted_user_id", userId);
        
        System.out.println("删除用户成功: ID=" + userId);
        return ResponseEntity.ok(
            ApiResponse.success("用户删除成功", result)
        );
    }
    
    /**
     * 搜索用户
     * 支持按姓名、邮箱、标签搜索
     */
    @GetMapping("/users/search")
    public ResponseEntity<ApiResponse<List<UserResponse>>> searchUsers(
            @RequestParam @NotBlank @Size(min = 1) String q) {
        
        List<UserResponse> users = userStorage.searchUsers(q);
        
        System.out.println("搜索用户: 关键词='" + q + "', 结果数=" + users.size());
        return ResponseEntity.ok(
            ApiResponse.success("搜索完成，找到 " + users.size() + " 个用户", users)
        );
    }
    
    /**
     * 获取用户统计信息
     */
    @GetMapping("/users/stats")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getUserStats() {
        List<UserResponse> allUsers = userStorage.getAllUsers();
        
        long totalUsers = allUsers.size();
        long activeUsers = allUsers.stream()
            .filter(user -> user.getStatus() == UserStatus.ACTIVE)
            .count();
        long inactiveUsers = allUsers.stream()
            .filter(user -> user.getStatus() == UserStatus.INACTIVE)
            .count();
        long suspendedUsers = allUsers.stream()
            .filter(user -> user.getStatus() == UserStatus.SUSPENDED)
            .count();
        
        // 统计标签分布
        Map<String, Long> tagCounts = allUsers.stream()
            .flatMap(user -> user.getTags().stream())
            .collect(Collectors.groupingBy(
                tag -> tag,
                Collectors.counting()
            ));
        
        Map<String, Object> statusDistribution = new HashMap<>();
        statusDistribution.put("active", activeUsers);
        statusDistribution.put("inactive", inactiveUsers);
        statusDistribution.put("suspended", suspendedUsers);
        
        Map<String, Object> stats = new HashMap<>();
        stats.put("total_users", totalUsers);
        stats.put("status_distribution", statusDistribution);
        stats.put("tag_distribution", tagCounts);
        stats.put("generated_at", LocalDateTime.now());
        
        return ResponseEntity.ok(
            ApiResponse.success("获取统计信息成功", stats)
        );
    }
}

// ============================================================================
// 5. 全局异常处理 (相当于Python的exception_handler)
// ============================================================================

/**
 * 全局异常处理器
 * 相当于Python的@app.exception_handler
 */
@ControllerAdvice
class GlobalExceptionHandler {
    
    /**
     * 处理验证异常
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseEntity<ApiResponse<Object>> handleValidationException(
            ConstraintViolationException e) {
        
        String message = e.getConstraintViolations().stream()
            .map(ConstraintViolation::getMessage)
            .collect(Collectors.joining(", "));
        
        System.out.println("验证异常: " + message);
        return ResponseEntity.badRequest()
            .body(ApiResponse.error("参数验证失败: " + message));
    }
    
    /**
     * 处理非法参数异常
     */
    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity<ApiResponse<Object>> handleIllegalArgumentException(
            IllegalArgumentException e) {
        
        System.out.println("非法参数异常: " + e.getMessage());
        return ResponseEntity.badRequest()
            .body(ApiResponse.error(e.getMessage()));
    }
    
    /**
     * 处理通用异常
     */
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ApiResponse<Object>> handleGeneralException(Exception e) {
        System.err.println("未处理异常: " + e.getClass().getSimpleName() + " - " + e.getMessage());
        e.printStackTrace();
        
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
            .body(ApiResponse.error("内部服务器错误"));
    }
}

// ============================================================================
// 6. 应用程序主类
// ============================================================================

/**
 * SpringBoot应用程序主类
 * 相当于Python的if __name__ == "__main__"
 */
@SpringBootApplication
public class SpringBootWebMvcApplication {
    
    public static void main(String[] args) {
        System.out.println("启动SpringBoot用户管理系统...");
        SpringApplication.run(SpringBootWebMvcApplication.class, args);
        System.out.println("SpringBoot应用启动完成");
    }
}

// ============================================================================
// 7. 配置文件 application.yml (需要单独创建)
// ============================================================================

/*
# application.yml 配置文件内容
# 相当于Python的uvicorn.run()配置

server:
  port: 8080
  servlet:
    context-path: /

spring:
  application:
    name: springboot-user-management
  
  # 数据库配置（如果使用JPA）
  # datasource:
  #   url: jdbc:h2:mem:testdb
  #   driver-class-name: org.h2.Driver
  #   username: sa
  #   password: 
  
  # JPA配置
  # jpa:
  #   hibernate:
  #     ddl-auto: create-drop
  #   show-sql: true

# 日志配置
logging:
  level:
    com.example.demo: INFO
    org.springframework.web: DEBUG
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} - %logger{36} - %level - %msg%n"

# Swagger配置（如果使用SpringDoc）
springdoc:
  api-docs:
    path: /api-docs
  swagger-ui:
    path: /swagger-ui.html
*/

// ============================================================================
// 8. Maven依赖配置 pom.xml (需要单独创建)
// ============================================================================

/*
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>springboot-user-management</artifactId>
    <version>1.0.0</version>
    <name>SpringBoot User Management</name>
    <description>SpringBoot WebMVC用户管理系统示例</description>
    
    <properties>
        <java.version>11</java.version>
    </properties>
    
    <dependencies>
        <!-- SpringBoot Web Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <!-- SpringBoot Validation -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        
        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- SpringDoc OpenAPI (Swagger) -->
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-ui</artifactId>
            <version>1.6.9</version>
        </dependency>
        
        <!-- SpringBoot Test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
*/

// ============================================================================
// 9. FastAPI vs SpringBoot WebMVC 详细对比总结
// ============================================================================

/*
FastAPI vs SpringBoot WebMVC 详细对比:

1. 项目结构:
   - FastAPI: 单文件即可运行，结构简单
   - SpringBoot: 需要Maven/Gradle项目结构，配置文件

2. 依赖管理:
   - FastAPI: pip install fastapi uvicorn
   - SpringBoot: Maven/Gradle管理复杂依赖树

3. 路由定义:
   - FastAPI: @app.get("/users") 装饰器
   - SpringBoot: @GetMapping("/users") 注解

4. 数据验证:
   - FastAPI: Pydantic自动验证，声明式
   - SpringBoot: Bean Validation，需要@Valid

5. 依赖注入:
   - FastAPI: Depends()函数，简单直观
   - SpringBoot: @Autowired注解，基于类型

6. 异常处理:
   - FastAPI: @app.exception_handler装饰器
   - SpringBoot: @ControllerAdvice + @ExceptionHandler

7. API文档:
   - FastAPI: 自动生成，零配置
   - SpringBoot: 需要SpringDoc/Swagger配置

8. 异步支持:
   - FastAPI: 原生async/await
   - SpringBoot: 需要WebFlux或CompletableFuture

9. 启动时间:
   - FastAPI: 秒级启动
   - SpringBoot: 需要几秒到十几秒

10. 内存占用:
    - FastAPI: 较低内存占用
    - SpringBoot: 较高内存占用（JVM开销）

11. 开发体验:
    - FastAPI: 代码简洁，开发快速
    - SpringBoot: 代码冗长，但IDE支持好

12. 生态系统:
    - FastAPI: 新兴，生态相对较小
    - SpringBoot: 成熟，企业级生态丰富

13. 学习曲线:
    - FastAPI: 相对简单，Python开发者容易上手
    - SpringBoot: 较复杂，需要了解Spring生态

14. 性能:
    - FastAPI: 高性能，接近Node.js和Go
    - SpringBoot: 性能良好，但不如FastAPI

15. 部署:
    - FastAPI: Docker容器化简单
    - SpringBoot: 传统JAR部署或容器化
*/